package com.lk.config;

import com.lk.customer.CustomerServerAccessDeniedHandler;
import com.lk.customer.CustomerServerAuthenticationEntryPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.ReactiveAuthenticationManager;
import org.springframework.security.config.web.server.SecurityWebFiltersOrder;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;
import org.springframework.security.oauth2.server.resource.web.server.ServerBearerTokenAuthenticationConverter;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.authentication.AuthenticationWebFilter;

import javax.sql.DataSource;

@Configuration
public class SecurityConfig {
    @Autowired
    private DataSource dataSource;
    @Autowired
    private AccessManager accessManager;

    @Autowired
    private CustomerServerAccessDeniedHandler customerServerAccessDeniedHandler;
    @Autowired
    private CustomerServerAuthenticationEntryPoint customerServerAuthenticationEntryPoint;

    @Bean
    SecurityWebFilterChain webFluxSecurityFilterChain(ServerHttpSecurity http) throws Exception {
        accessManager.initIgnore();
        //token管理器
        ReactiveAuthenticationManager tokenAuthenticationManager = new ReactiveJdbcAuthenticationManager(new JdbcTokenStore(dataSource));
        //认证过滤器
        AuthenticationWebFilter authenticationWebFilter = new AuthenticationWebFilter(tokenAuthenticationManager);
        authenticationWebFilter.setServerAuthenticationConverter(new ServerBearerTokenAuthenticationConverter());

        http.httpBasic().disable()
                .exceptionHandling()
                // 配置应用程序请求身份验证时要执行的操作
                .authenticationEntryPoint(customerServerAuthenticationEntryPoint)
                // 访问拒绝处理程序
                .accessDeniedHandler(customerServerAccessDeniedHandler)
                .and()
                .csrf().disable()
                .authorizeExchange()
                // 预检请求放过
                .pathMatchers(HttpMethod.OPTIONS).permitAll()
                // 其他的请求 都需要经过访问管理器
                .anyExchange().access(accessManager)
                .and()
                //oauth2认证过滤器
                .addFilterAt(authenticationWebFilter, SecurityWebFiltersOrder.AUTHENTICATION);
        return http.build();
    }
}
